package phase03.module04.dao;

import com.alibaba.druid.pool.DruidDataSourceFactory;
import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.ZkClient;

import javax.sql.DataSource;
import java.util.Properties;

/**
 * 单例Druid连接池创建DataSource，第一次创建默认的数据库连接信息，并在ZooKeeper创建节点/mysql
 * 监听/mysql的data change，当发生变化时，更新配置信息，把ds置为null
 * web工程获取DataSource时，就会用新的数据库配置信息创建DataSource
 * @author Alex Zhang
 */
public class DbPool {
    private static Properties properties;
    private static volatile DataSource ds = null;

    static {
        final String mysqlZkPath = "/mysql";
        final String zkServer = "node1:2181";
        ZkClient zk = new ZkClient(zkServer);
        if (zk.exists(mysqlZkPath)) {
            properties = zk.readData(mysqlZkPath);
        } else {
            properties = new Properties();
            properties.setProperty("driverClassName", "");
            properties.setProperty("driver", "com.mysql.cj.jdbc.Driver");
            properties.setProperty("url", "jdbc:mysql://node3:3306/pz3?useSSL=false&characterEncoding=UTF-8");
            properties.setProperty("username", "root");
            properties.setProperty("password", "dont4get");
            properties.setProperty("initialSize", "5");
            properties.setProperty("maxACtive", "10");
            properties.setProperty("maxWait", "3000");
            zk.createPersistent(mysqlZkPath);
            zk.writeData(mysqlZkPath, properties);
        }
        zk.subscribeDataChanges(mysqlZkPath, new IZkDataListener() {
            @Override
            public void handleDataChange(String dataPath, Object data) {
                System.out.println("db conf changed." + data);
                properties = (Properties) data;
                ds = null;
            }

            @Override
            public void handleDataDeleted(String dataPath) {
            }
        });
    }

    private DbPool() {}

    public static DataSource getDataSource() {
        if(null == ds) {
            synchronized (DbPool.class) {
                if (null == ds) {
                    try {
                        ds = DruidDataSourceFactory.createDataSource(properties);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return ds;
    }

}
